home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / SVGATextMode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-31  |  14.2 KB  |  467 lines

  1. /*  SVGATextMode -- An SVGA textmode manipulation/enhancement tool
  2.  *
  3.  *  Copyright (C) 1995,1996  Koen Gadeyne
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20.  
  21. /***
  22.  *** SVGATextMode.c: the great big wolf
  23.  ***
  24.  *** Edited on 132x64 screen. Hence the LONG lines. For best viewing conditions, use this program to make itself more readable :-)
  25.  ***/
  26.  
  27.  
  28. #include "misc.h"
  29. #include "ttyresize.h"       /* must be first ! */
  30.  
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <unistd.h>
  35. #include <math.h>
  36.  
  37. #ifndef DOS
  38. #  include <asm/io.h>
  39. #  include <linux/fs.h>
  40. #  include <sys/ioctl.h>
  41. #  include <sys/kd.h>
  42. #endif
  43.  
  44. /*
  45.  * this is not very clean, but it throws out all unix tty resizing stuff, which also makes it compile clean in DOS
  46.  * However, DOS DOES support resizing. Don't let that confuse you. This is a hack for easy compiling.
  47.  */
  48. #ifdef DOS
  49. #  define NO_RESIZE
  50. #endif
  51.  
  52.  
  53. #define CHIPSETREC 1  /* included chipset definition struct */
  54. #include "chipset.h"
  55. #include "vga_prg.h" 
  56. #include "setclock.h"
  57. #include "validate.h"
  58. #include "file_ops.h"
  59. #include "messages.h"
  60. #include "run_extprog.h"
  61. #include "dump_cfgdata.h"
  62. #include "XFREE/xfree_compat.h"
  63.  
  64. /*
  65.  * this adds all the global variables that hold the data from the config file.
  66.  */
  67. #include "cfg_data.h"
  68.  
  69. /*
  70.  * other global variables
  71.  */
  72.  
  73. char *CommandName;
  74. char *ConfigFile=CONFIGFILE; 
  75. bool debug_messages=FALSE;
  76.  
  77. /*
  78.  * yacc parser functions
  79.  */
  80.  
  81. extern int yyparse(void);
  82. extern FILE *yyin;
  83. #define param_file yyin
  84.  
  85. void usage()
  86. {
  87.      PMESSAGE(("version %s. (c) 1995,1996 Koen Gadeyne.\n"
  88.      "  Usage: %s [options] [textmodelabel]\n"
  89.      "  Options: -n  Don't program VGA hardware\n"
  90.      "               (parse config file and report mode parameters)\n"
  91.      "           -d  print debugging information\n"
  92.      "           -h  print usage information\n"
  93.      "           -r  don't run ResetProg\n"
  94.      "           -f  don't run FontProg\n"
  95.      "           -c  don't change pixel clock\n"
  96.      "           -v  don't validate H/V frequencies with limits in config file\n"
  97.      "           -s  scan for all valid text modes from the config file\n"
  98.      "           -a  always do a full resize, even if changing to same size screen\n"
  99.      "           -m  allow 1x1 screen to avoid `VT_RESIZE: out of memory' error\n"
  100.      "               (relatively dangerous - read SVGATextMode(8) manual first!)\n"
  101.      "           -t <ConfigFile>\n"
  102.      "               Use <ConfigFile> instead of the default (%s)\n"
  103.      "  Textmodelabel: an existing label from the config file\n"
  104.      "    (optional when `DefaultMode' defined in config file)\n",
  105.      VERSION, CommandName, CONFIGFILE));
  106. }
  107.  
  108. /****************************************************************************************************************************/
  109.  
  110.  
  111. int main (int argc, char* argv[])
  112. {
  113.   int debug_level=0;
  114.   
  115.   char *req_label=NULL;
  116.   
  117.   bool program_hardware=TRUE;
  118.   bool scanmodes=FALSE;
  119.   bool validate=TRUE;
  120.   bool alwaysresize=FALSE;
  121.   bool resize1x1=FALSE;
  122.   int c;
  123.     
  124.   bool sresize=TRUE;         /* will be set when screen has been resized and vice-versa */
  125.   
  126.   bool run_resetprog=TRUE, run_fontprog=TRUE, run_pixclock=TRUE;
  127.  
  128.   t_mode *curr_textmode;
  129.        
  130.  /*
  131.   * command-line argument parsing
  132.   */
  133.  
  134.   CommandName = argv[0];
  135.  
  136.   while ((c = getopt (argc, argv, "ndhrfcsamvt:")) != EOF)
  137.     switch (c)
  138.     {
  139.       case 'n': program_hardware=FALSE;
  140.                 break;
  141.       case 'd': debug_level++;
  142.                 debug_messages=TRUE;
  143.                 break;
  144.       case 'h': usage();
  145.                 exit(0);
  146.                 break;
  147.       case 'r': run_resetprog=FALSE;
  148.                 break;
  149.       case 'f': run_fontprog=FALSE;
  150.                 break;
  151.       case 'c': run_pixclock=FALSE;
  152.                 break;
  153.       case 's': scanmodes=TRUE;
  154.                 break;
  155.       case 'm': resize1x1=TRUE;
  156.                 break;
  157.       case 'v': validate=FALSE;
  158.                 break;
  159.       case 'a': alwaysresize=TRUE;
  160.                 break;
  161.       case 't': ConfigFile=safe_strdup(optarg);
  162.                 break;
  163.       case '?': usage();
  164.                 PERROR(("Bad option '-%c'\n",(char)optopt));
  165.                 exit(-1);
  166.                 break;
  167.       default: PERROR(("getopt returned unknown token '%c'.\n",c));
  168.     }
  169.  
  170.   PVERSION;
  171.   PDEBUG(("Debug level: %d\n", debug_level));
  172.     
  173.  /*
  174.   * open parameter file, parse the sucker, close up again.
  175.   */
  176.   param_file = open_param_file(ConfigFile);
  177.   PDEBUG(("Parsing Config file...\n"));
  178.   while (!feof(yyin)) { yyparse(); }
  179.   fclose(param_file);
  180.  
  181.  /*
  182.   * Do some sanity checks
  183.   */
  184.  
  185.   sanitize_cfgfile_data();
  186.    
  187.  /*
  188.   * show all parsed data
  189.   */
  190.   
  191.   if (debug_level>0) dump_cfgdata(debug_level);
  192.  
  193.   /*
  194.    * switch between "scan" mode or normal mode
  195.    */
  196.   
  197.   if (scanmodes)
  198.   {
  199.     scan_valid_modes(validate);
  200.     exit(0);
  201.   }
  202.   else   /* normal program-a-new-textmode mode */
  203.   {
  204.    /*
  205.     * look for a text mode label. If none, look for a "defaultmode" in the config file
  206.     */
  207.     req_label=NULL;
  208.  
  209.     /* if requested mode is on command line: use that one */
  210.     if (optind < argc) req_label = argv[optind];
  211.     
  212.     /* defaultmode in config file is default when not overridden by command line */
  213.     else if (defaultmode)
  214.       {
  215.         req_label = defaultmode;
  216.         PDEBUG(("No mode label on command line: using '%s' as default mode\n", req_label));
  217.       }
  218.  
  219.     /* none of the above: eject! eject! */
  220.     else
  221.       {
  222.         usage();
  223.         PERROR(("No textmode label on commandline, and no 'DefaultMode' in config file.\n"));
  224.       }
  225.   }
  226.  
  227.  
  228. /* find last occurence of requested text mode line: This will allow
  229.  * user-patched mode lines at end of TextConfig file to get preference over the
  230.  * ones above it, which normally are the default ones (as suggested by Kenneth
  231.  * Albanowski). Due to the way the file is parsed, the last lines are first in
  232.  * the config file data structure, so we match the first occurence in the data base.
  233.  */
  234.  
  235.   curr_textmode = text_mode_list;
  236.   while (curr_textmode)
  237.   {
  238.     if (!strcasecmp(curr_textmode->name, req_label)) break;
  239.     curr_textmode = curr_textmode->next;
  240.   }
  241.   
  242.   if (!curr_textmode) PERROR(("Text Mode `%s' could not be found in the config file.\n", req_label));
  243.  
  244.   /* requested mode found in data base. show some information */
  245.   PDEBUG(("Found requested text mode in config file:\n"));
  246.   dump_mode(curr_textmode);
  247.   
  248.   /* scale the cursor to fit the chosen font size */
  249.   cursor_start = (cursor_start * curr_textmode->FontHeight) / 32;
  250.   cursor_end = (cursor_end * curr_textmode->FontHeight) / 32;
  251.   PDEBUG(("Cursor start-end = %d-%d\n", cursor_start, cursor_end));
  252.  
  253.   /* scale underline position to fit current font size */
  254.   if (underline_pos>=0) underline_pos = (underline_pos * curr_textmode->FontHeight) / 32;
  255.   PDEBUG(("Underline pos. will be: %d\n", underline_pos));
  256.  
  257.  
  258.  /*
  259.   * show the user what mode will be programmed, and also check if it is allowed.
  260.   */
  261.   
  262.   check_and_show_mode(curr_textmode, validate);
  263.  
  264.  /*
  265.   * start changing some things now.
  266.   */
  267.  
  268.   if (program_hardware)
  269.   {
  270.      sresize = check_if_resize(curr_textmode->cols, curr_textmode->rows);
  271.  
  272.      /* FIRST check for IO permissions, to avoid first resizing the screen, and then seeing that we can't
  273.         write to the VGA regs */
  274.          
  275.      get_VGA_io_perm(chipset);
  276.      
  277.      /* sync disks if requested. Is there any way to do this and be SURE _all_ data has been flushed? */
  278.      if (OFLG_ISSET(OPT_SYNC))
  279.      {
  280.        PMESSAGE(("Syncing disks...\n"));
  281.        sync(); sleep(2); /* same as in "reboot" command. Hopefully enough */
  282.      }
  283.      
  284. #ifndef DOS
  285. #  ifndef NO_RESIZE
  286.    
  287.      if (sresize || alwaysresize)
  288.      {
  289.       /*
  290.        * first see if current kernel version supports resizing.
  291.        */
  292.        
  293.        if (!check_kernel_version(1,1,54, "Virtual Terminal resizing"))
  294.          PERROR(("Screen resizing not allowed (kernel version must be >= 1.1.54). Use a non-resizing text mode, or upgrade your kernel.\n"));
  295.  
  296.       /*
  297.        * Resize the screen. Still needs LOTS more error checking to avoid dropping out in the middle, leaving
  298.        * the user with a garbled screen.
  299.        *
  300.        * sresize will be TRUE when resizing tty's should be forced (due to the 2nd attempt do_VT_RESIZE will do
  301.        * when not enough memory is free).
  302.        *
  303.        */
  304.  
  305.         /*
  306.          * ALWAYS do a VT_RESIZE, even if we already did a VT_RESIZEX on a 1.3.3 or higher kernel, 
  307.          * until those kernel programmers make this unambiguous
  308.          */
  309.       
  310.        if (do_VT_RESIZE(curr_textmode->cols, curr_textmode->rows, resize1x1)) sresize=TRUE;
  311.          
  312.        if (check_kernel_version(1,3,3, "VT_RESIZEX"))
  313.          {
  314.            /*
  315.             * VDisplay must de divided by 2 for DoubleScan modes,
  316.             * or VT_RESIZEX will fail -- until someone fixes the kernel
  317.             * so it understands about doublescan modes.
  318.             */
  319.            if (do_VT_RESIZEX(curr_textmode->cols,
  320.                              curr_textmode->rows,
  321.                              curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1),
  322.                              curr_textmode->FontHeight,
  323.                              curr_textmode->HDisplay/8*curr_textmode->FontWidth,
  324.                              curr_textmode->FontWidth, resize1x1)) sresize=TRUE;
  325.          }
  326.          
  327.       /*
  328.        * resize terminals. If specified in "terminals" line, do just those.
  329.        * If not specified, find out which ones are active, and resize those.
  330.        * This is obsoleted by kernel v1.3.3 and up (they do it themselves upon
  331.        * a call to VT_RESIZE)
  332.        */
  333.           
  334.        if (!check_kernel_version(1,3,3, "Automatic TTY resizing (SIGWINCH)"))
  335.        {
  336.          if (p_terminals) resize_specified_vts(curr_textmode->cols, curr_textmode->rows);
  337.            else resize_active_vts(curr_textmode->cols, curr_textmode->rows);
  338.        }
  339.      }
  340.  
  341. #  else 
  342.      /*
  343.       * no resizing support: do NOT allow resizing. Check if some stubborn moosehead tries anyway.
  344.       */
  345.       
  346.       if (sresize) PERROR(("Resizing is not allowed (NO_RESIZE defined during compilation).\n"));
  347. #  endif
  348. #else   /* DOS */
  349.       if (sresize) resize_DOS(curr_textmode->cols, curr_textmode->rows);
  350. #endif   
  351.  
  352.    /*
  353.     * now get to the REAL hardware stuff !
  354.     */
  355.  
  356.     unlock(chipset);
  357.  
  358.     special(chipset); /* change chipset-specific things, if needed */
  359.  
  360.     if (run_pixclock)
  361.       do_clock(chipset, curr_textmode->pixelClock);
  362.     else PDEBUG(("Clock will NOT be programmed! (due to command line switch '-c') !\n"));
  363.     
  364.     Set_MAX_SCANLINE (curr_textmode->FontHeight);
  365.     
  366.     set_V_timings(curr_textmode->VDisplay, curr_textmode->VSyncStart, curr_textmode->VSyncEnd, curr_textmode->VTotal);
  367.     set_H_timings(curr_textmode->HDisplay, curr_textmode->HSyncStart, curr_textmode->HSyncEnd, curr_textmode->HTotal);
  368.     
  369.     interlace(chipset, curr_textmode);
  370.     
  371.     Outbit_CRTC(0x09, 7, MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 1 : 0);
  372.  
  373.     Set_CURSOR_START(cursor_start) ; Set_CURSOR_END(cursor_end);
  374.     
  375.     if (underline_pos>=0) Set_Underline_location(underline_pos);
  376.  
  377.     Set_HSYNC_POLARITY(curr_textmode->hpol) ; Set_VSYNC_POLARITY(curr_textmode->vpol);
  378.     
  379.     /* set sync-on-green on special RAMDAC's */
  380.     if ( (clock_data.clockchiptype==CLKCHIP_TI3026) || (clock_data.clockchiptype==CLKCHIP_TI3025) )
  381.       set_ti_SOG( (OFLG_ISSET(OPT_SOG)) );
  382.       
  383.     Outbit_ATR_CTL(0x10, 3, OFLG_ISSET(OPT_16COLOR) ? 0 : 1);
  384.  
  385.     Set_Textmode;  /* just in case some jerk set us in graphics mode. Or if he's in X-windows: surprise surprise ! */
  386.  
  387. #ifndef DOS
  388.     /* set console to text mode */
  389.     ioctl(opentty("/dev/console"), KDSETMODE, KD_TEXT);
  390. #endif
  391.  
  392.     if (set_charwidth(curr_textmode->FontWidth)) PERROR(("Illegal character width: %d\n",curr_textmode->FontWidth));
  393.  
  394.     Outb_ATR_CTL(0x11, bordercolor);
  395.     
  396.     SCREEN_ON;
  397.     
  398.     /* could do a safe_wait_vsync() here to check if we have some refresh */
  399.  
  400.   }
  401.   
  402.  /*
  403.   * call the external font loading program, if enabled by the 'option loadfont' line
  404.   */
  405.  
  406.  if ((program_hardware) && (chipset==CS_S3))
  407.  {
  408.    /* S3 high speed text mode cannot be run when font loading is not enabled */
  409.    S3_StartHSText_FontLoad(curr_textmode->pixelClock, FALSE);
  410.  }
  411.  
  412.  if (OFLG_ISSET(OPT_LOADFONT) && (program_hardware) && (run_fontprog))
  413.  {
  414.    if (!(font_data.font_table[curr_textmode->FontWidth-8][curr_textmode->FontHeight-1]))
  415.    {
  416.      PWARNING(("Font loading enabled, but no font specified for %dx%d text mode.\n", curr_textmode->FontWidth, curr_textmode->FontHeight));
  417.      PWARNING(("No font will be loaded.\n"));
  418.    }
  419.    else
  420.    {
  421.      char tempstr[1024]="";
  422.      int result=0;
  423.      sprintf(tempstr,"%s %s/%s", font_data.fontprogpath, font_data.fontpath,
  424.              font_data.font_table[curr_textmode->FontWidth-8][curr_textmode->FontHeight-1]);
  425.  
  426.      if (chipset==CS_S3)
  427.      {
  428.        PDEBUG(("Executing external command %s'\n", tempstr));
  429.        S3_StartHSText_FontLoad(curr_textmode->pixelClock, TRUE);
  430.        result = Run_extern_Prog_pipe(tempstr);
  431.        S3_EndHSText_FontLoad();
  432.        show_extout();
  433.        if (result<0) PWARNING(("External program call `%s' through pipe failed.\n", tempstr));
  434.      }
  435.      else
  436.      {
  437.        Run_extern_Prog(tempstr);
  438.      }
  439.    }
  440.  }
  441.  
  442.  
  443. #ifndef NO_RESIZE
  444.  /*~
  445.   * call the reset program (which could be used to notify applications about the screen changes)
  446.   * But only when the screen has been resized.
  447.   *
  448.   * Of course, nobody needs this when resizing is impossible (NO_RESIZE defined)
  449.   */
  450.  
  451.  if ((resetprogpath) && (program_hardware) && (run_resetprog))
  452.  {
  453.     char tempstr[1024]="";
  454.     if (!sresize && !alwaysresize)
  455.       PDEBUG(("Screen not resized. ResetProg not executed.\n"));
  456.     else
  457.     {
  458.       sprintf(tempstr,"%s %d %d", resetprogpath, curr_textmode->cols, curr_textmode->rows);
  459.       Run_extern_Prog(tempstr);
  460.     }
  461.   }       
  462. #endif
  463.  
  464.   return(0);
  465. }
  466.  
  467.